package com.yystar.security.support.util;

import java.math.BigDecimal;
import java.text.DecimalFormat;

import org.apache.commons.lang3.StringUtils;

public abstract class AppMathUtil {
	public static double floor(BigDecimal b, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		return b.divide(BigDecimal.valueOf(1), scale, BigDecimal.ROUND_FLOOR).doubleValue();
	}

	public static double round(BigDecimal b, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		return b.divide(BigDecimal.valueOf(1), scale, BigDecimal.ROUND_HALF_DOWN).doubleValue();
	}

	public static double roundDown(BigDecimal b, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		return b.divide(BigDecimal.valueOf(1), scale, BigDecimal.ROUND_DOWN).doubleValue();
	}

	public static double roundUp(BigDecimal b, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		return b.divide(BigDecimal.valueOf(1), scale, BigDecimal.ROUND_UP).doubleValue();
	}
	
	/**
	 * Round
	 * @param v
	 * @param scale
	 * @return
	 */
	public static double round(double v, int scale) {
		if (Double.isInfinite(v) || Double.isNaN(v)) {
			return v;
		}
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		BigDecimal b = new BigDecimal(Double.toString(v));
		BigDecimal one = new BigDecimal("1");
		return b.divide(one, scale, BigDecimal.ROUND_HALF_DOWN).doubleValue();
	}
	
	/**
	 * Floor
	 * @param v
	 * @param scale
	 * @return
	 */
	public static double floor(double v, int scale) {
		if (Double.isInfinite(v) || Double.isNaN(v)) {
			return v;
		}
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		BigDecimal b = new BigDecimal(Double.toString(v));
		BigDecimal one = new BigDecimal("1");
		return b.divide(one, scale, BigDecimal.ROUND_FLOOR).doubleValue();
	}
	
	/**
	 * Format decimal
	 * @param decimal
	 * @param formatStr
	 * @return
	 */
	public static String format(BigDecimal decimal, String formatStr) {
		if (StringUtils.isEmpty(formatStr))
			formatStr = "0.000";
		DecimalFormat df = new DecimalFormat(formatStr); 
		return df.format(decimal);
	}
	
	/**
	 * 0.000
	 * format price in system.
	 * @param price
	 * @return
	 */
	public static String formatPrice(double price){
		return format(BigDecimal.valueOf(price), "0.000");
	}
	
	/**
	 * Calculate m^n
	 * @param m
	 * @param n
	 * @return
	 */
	public static long power(long m, int n) {
		long r = 1;
        while (n-- >= 1) {
            r *= m;
        }
        return r;
	}
		
	public static void main(String[] args) {
//		System.out.println(WMathUtility.power(2, 5));
		BigDecimal a = new BigDecimal(""+734);
//		BigDecimal a = BigDecimal.valueOf(25);
//		BigDecimal b = BigDecimal.valueOf(0.8102);
		BigDecimal b = new BigDecimal(""+0.8102);
		double c = AppMathUtil.roundDown(a.multiply(b),3);
		System.out.println(a.multiply(b));//0.8102 * 1000 * 734/1000
		System.out.println(c);//0.8102 * 1000 * 734/1000
		System.out.println(0.8102 * 25);
	}

}
